---
title: How to use a standalone Expo module
description: Learn how to use a standalone module created with create-expo-module in your project by using a monorepo or publishing the package to npm.
---

import { Terminal } from '~/ui/components/Snippet';

**The recommended way to create an Expo module** inside an existing application is described in the [Expo Modules API: Get started](/modules/get-started/) guide. This page walkthrough two additional methods of using a module created with `create-expo-module` inside an existing project:

- [Configure a monorepo](#use-a-monorepo)
- [Publish the module to npm](#publish-the-module-to-npm)

These methods are useful if you still want to keep the module separate from the application or share it with other developers.

## Use a monorepo

For this guide, we assume that you have the following project structure:

- **apps/** - Contains multiple projects, including React Native apps.
- **packages/** - Contains different packages used by your apps.
- **package.json** - Root package file containing Yarn workspaces config.

If you need to familiarize yourself with configuring your project as a monorepo, see [**Working with monorepos**](/guides/monorepos/) guide.

### 1. Initialize a new module

Once you have set up the basic monorepo structure, create a new module using `create-expo-module` with the flag `no-example` to skip creating the example app:

<Terminal cmd={['$ npx create-expo-module packages/expo-settings --no-example']} />

### 2. Set up workspace

Now, let's configure `autolinking` so all your apps can use the newly created module. Add the following block to the **package.json** file of each app under the **apps** directory:

```json package.json
"expo": {
  "autolinking": {
    "nativeModulesDir": "../../packages"
  }
}
```

### 3. Run the module

Run one of the apps to ensure everything is working. Then, start the TypeScript compiler inside **packages/expo-settings** to watch for changes and rebuild the module's JavaScript:

<Terminal
  cmdCopy="cd packages/expo-settings && npm run build"
  cmd={['$ cd packages/expo-settings', '$ npm run build']}
/>

Open another terminal window, choose an app from the **apps** directory, and run the `prebuild` command. You'll have to repeat these steps for all apps inside your monorepo to use the new module.

<Terminal cmd={['$ npx expo prebuild --clean']} />

Compile and run the app with the following command:

<Terminal
  cmdCopy="npx expo run:ios"
  cmd={[
    '# Run the app on Android',
    '$ npx expo run:android',
    '# Run the app on iOS',
    '$ npx expo run:ios',
  ]}
/>

You can now use the module inside your app. To test this, let's edit the **App.js** file in the app and render the text message from the `expo-settings` module:

```jsx App.js
import * as Settings from 'expo-settings';
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';

export default function App() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>{Settings.hello()}</Text>
      <StatusBar style="auto" />
    </View>
  );
}
```

After this configuration, you'll see a text that says "Hello world! 👋" in the app.

## Publish the module to npm

You can publish the module on npm and then add it to your project by installing it as a dependency.

### 1. Initialize a new module

Start by creating a new module using `create-expo-module`. Pay attention to each prompt as you'll publish this library, and choose a unique name for your npm package.

<Terminal cmd={['$ npx create-expo-module expo-settings']} />

### 2. Run the example project

Run the example project to make sure everything is working. Then, start the TypeScript compiler to watch for changes and rebuild the JavaScript module.

<Terminal
  cmd={[
    '# Run this in the root of the project to start the TypeScript compiler',
    '$ npm run build',
  ]}
/>

Open another terminal window, compile and run the example app:

<Terminal
  cmdCopy="cd example && npx expo run:ios"
  cmd={[
    '$ cd example',
    '# Run the example app on Android',
    '$ npx expo run:android',
    '# Run the example app on iOS',
    '$ npx expo run:ios',
  ]}
/>

### 3. Publish the package to npm

To publish your package to npm, you need to have a npm account. If you don't have one, create it on [the npm website](https://www.npmjs.com/signup). Once you have an account, log in using the following command:

<Terminal cmd={['$ npm login']} />

Then, navigate to the root of your module and publish your module running:

<Terminal cmd={['$ npm publish']} />

Your module will now be published to npm and can be installed in other projects using `npm install`.

Apart from publishing your module to npm, there are other ways to use it in your project:

- Create a tarball of your module using `npm pack` and install it directly in your project by running `npm install /path/to/tarball`. It's useful to test your module locally before publishing it to npm or if you want to share it with others who don't have access to the npm registry.
- Run a local npm registry, such as [Verdaccio](https://verdaccio.org/), and install your module from there. This is useful for cases where you want to host your private npm registry to manage internal packages within a company or organization.
- [Publish a private package or use a private registry with EAS Builds](/build-reference/private-npm-packages/).

### 4. Test the published module

To test the published module in a new project, create a new app and install the module as a dependency:

<Terminal
  cmdCopy="npx create-expo-app my-app && cd my-app && npx expo install expo-settings"
  cmd={['$ npx create-expo-app my-app', '$ cd my-app', '$ npx expo install expo-settings']}
/>

You should now be able to use the module inside your app! To test it, edit the **App.js** in the app and render the text message from **expo-settings**.

```jsx App.js
import * as Settings from 'expo-settings';
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';

export default function App() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>{Settings.hello()}</Text>
      <StatusBar style="auto" />
    </View>
  );
}
```

To run your app locally, run the `prebuild` command and then compile the app.

<Terminal
  cmdCopy="npx expo prebuild --clean && npx expo run:ios"
  cmd={[
    '# Re-generate the native project directories from scratch',
    '$ npx expo prebuild --clean',
    '# Run the example app on Android',
    '$ npx expo run:android',
    '# Run the example app on iOS',
    '$ npx expo run:ios',
  ]}
/>

After this configuration, you'll see a text that says "Hello world! 👋" in the app.
